import json
import logging
import os
# import traceback
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.views import View
from django_redis import get_redis_connection
import datetime
import traceback

from Control.Serialization import serDistrict, serMobile, serMonitor
from big_screen.utils import tools as t, sys_setting as code
from big_screen.utils.paginator import page_request
from brocast.tasks import save_to_mysql
from .Serialization import serBlackRecord, serBlackCategory
from big_screen.redisOpration.AllOpration import massmarkOp, broadcastOp
from big_screen.utils.turn import blackrecord_turn
from Control.models import MobileInfo

errlog = logging.getLogger('Process')
Brlog = logging.getLogger('Broadcasting')
bodylog = logging.getLogger("body")

base_dir = os.path.dirname(os.path.dirname(os.path.dirname(
    os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))))


# √
class RecordingView(View):
    @classmethod
    def post(cls, request):
        """
        保存录音文件
        :param request:
        :return:
        """
        try:
            re = request.FILES
        except Exception as e:
            errlog.warning(e)
            return JsonResponse({'errmsg': '打开失败'})
        if re:
            ogg_dir = base_dir + '/static/mp3'
            for i in request.FILES:
                data = request.FILES[i]
                destination = open(os.path.join(ogg_dir, data.name), 'wb')
                for chunk in data.chunks():
                    destination.write(chunk)
                destination.close()
            con = {
                "errno": 10000,
                "errmsg": "success",
                'path': ogg_dir
            }
        else:
            re = request.POST
            errlog.warning('无文件')
            for k, v in re.items():
                errlog.info(v.encode('utf-8'))
            con = {
                "errno": 10001,
                "errmsg": "unsuccess",
            }
        return JsonResponse(con)


# √
class BroadcastTextView(View):
    # √
    @classmethod
    def get(cls, request):
        """
        获取黑广播
        1.根据条件检索黑广播记录:种类category,时间范围 starttime,endtime,设备phone,频点freq
        2.无条件获取白名单之外的黑广播信息
        3.限制数量
        :param request:
        :return:
        """
        # 接收数据
        # 判读是否有检索条件
        # if request.user.is_authenticated():
        # ----------------------------- 检索请求 -------------------------------
        ret = request.GET
        keys = ret.keys()
        if "0" in keys:
            request_json = eval(ret["0"])
        else:
            request_json = dict()
        limit, page = page_request(ret)
        # ----------------------------- 序列化器 --------------------------------
        s = serBlackRecord()
        # ------------------------------- 条件查询 ----------------------------------------------
        if request_json is not dict():
            info_list = s.select_info(request_json)
        # ---------------------------------- 无条件查询 --------------------------------
        else:
            info_list = s.get_info()
        # --------------------------------- 分页 -----------------------------------------
        paginator = Paginator(info_list, limit)
        content = list()
        for info in paginator.page(page):
            content.append(info)
        # ------------------------------- 返回 -------------------------------------------
        con = {
            'code': 'ok',
            "data": content,
            'count': paginator.count
        }
        return JsonResponse(con)

    # √
    @classmethod
    def post(cls, request):
        """
        上传黑广播
        1.保存数据库
        2.处理后保存在redis
        :param request:
        :return:
        """
        ret = eval(request.body.decode())
        # ------------------- 查看设备是否在系统中 --------------------
        s= serMobile()
        try:
            mob_obj=s.table.get(mobile=ret["phoneid"])
            if mob_obj.is_delete:
                con = {"code":code.STATUSCODE_UNSUCCESS,"msg":"该设备不在系统中"}
                return JsonResponse(con)
        except MobileInfo.DoesNotExist:
            con = {"code":code.STATUSCODE_UNSUCCESS,"msg":"该设备不在系统中"}
            return JsonResponse(con)
        else:
            bodylog.info(ret)
            # ------------------- 转格式 ---------------------------
            content = blackrecord_turn(ret)
            # **************** 放入task *****************
            save_to_mysql.delay(content)
            # ------------------- 缓存 -----------------------------
            # **************** 白名单过滤 *****************
            content = t.wh_filter_content(content)
            # *************** 海量点 *******************
            mass = massmarkOp()
            mass_content = list(map(mass.formmater_data, content))
            for con in mass_content:
                k, v = con
                mass.list_push(k, v)
            # ***************** 轮播表 ******************
            bro = broadcastOp()
            scroll_content = list(map(bro.formatter_scroll_info, content))
            for con in scroll_content:
                bro.list_push("scroll_n", con)
            # ****************** 热力图 ********************
            heatmap_content = list(map(bro.formatter_heatmap_info, content))
            for con in heatmap_content:
                bro.list_push("heatmap_n", con)
            # ------------------ 返回 --------------------------------
            con = {
                "code": code.STATUSCODE_SUCCESS,
                "msg": "success",
            }
            return JsonResponse(con)

    # √
    @classmethod
    def patch(cls, request):
        """
        修改黑广播
        １．修改黑广播的联系方式和备注
        :param request:
        :return:
        """
        ret = eval(request.body.decode())
        s = serBlackRecord()
        con = s.update_info(ret)
        return JsonResponse(con)


# √
class GetInfoView(View):
    @classmethod
    def get(cls, request):
        """
        检索表单所用信息
        获取一些基本信息 种类、所属地区等
        :param request:
        :return:
        """
        # ----------------- 请求 -----------------
        ret = request.GET
        errlog.info(ret)
        # ---------------- 序列化器 --------------
        dis = serDistrict()
        category = serBlackCategory()
        mobile = serMobile()
        monitor = serMonitor()
        # ---------------- 获取名单 --------------
        district_list = dis.get_info_list()
        category_list = category.get_info()
        # category_list = category.get_info_list()
        mobile_list = mobile.get_info_list()
        monitor_list = monitor.get_info_list()
        # ----------------- 组织数据 --------------
        con = {
            "district": district_list,
            "category": category_list,
            "mobile": mobile_list,
            "monitor": monitor_list
        }
        return JsonResponse(con)


# √
class RegionRetrievalView(View):
    @classmethod
    def get(cls, request):
        """
        根据区域对黑光播进行检索
        :param request:
        :return:
        """
        ret = request.GET
        limit, page = page_request(ret)
        # --------------------------- 序列化器 --------------------
        dis = serDistrict()
        bro = serBlackRecord()
        # --------------------------- 检索 ------------------------
        select_dict_bro = dict()
        select_dict_dis = dict()
        # ********* 时间 ***********
        time = int(ret.get("time"))
        if time is not -1:
            e_time = datetime.datetime.now()
            time_diff = datetime.timedelta(int(time))
            s_time = e_time - time_diff
            select_dict_bro["e_time"] = datetime.datetime.strftime(e_time, code.DATA_FORMATTER)
            select_dict_bro["s_time"] = datetime.datetime.strftime(s_time, code.DATA_FORMATTER)
        # ********* 区域 *************
        select_dict_dis["adcode"] = ret.get("adcode")
        # 市级区域id
        dis_obj = dis.select_info(select_dict_dis)
        dis_id = dis_obj[0].get("id")
        # 市级数据
        select_dict_bro["district"] = dis_id
        info_list = bro.select_info(select_dict_bro)
        # 下属区县级id
        sub_dis_obj =list( dis.table.filter(superior=dis_id).values("id"))
        for sub in sub_dis_obj:
            # 下级区县级数据
            sub_select_dict=dict()
            sub_select_dict["district"]=sub.get("id")
            sub_list=bro.select_info(sub_select_dict)
            info_list.extend(sub_list)
        # --------------------------- 分页 -------------------------
        paginator = Paginator(info_list, limit)
        content = list()
        for info in paginator.page(page):
            content.append(info)
        # --------------------------- 返回 -------------------------
        return JsonResponse({"code": code.STATUSCODE_SUCCESS, "msg": "success", "data": content, "count": paginator.count})


# √
class ChartView(View):
    # √
    @classmethod
    def get(cls, request):
        """
        图表数据
        :param request:
        :return:
        """
        if request.user.is_authenticated():
            # --------------- 读配置 ---------------------------
            s = t.setting()
            start_day = s.start_time
            # ---------------- 建立redis连接 -------------------
            chart_con = get_redis_connection('broadcast')
            chart_data = chart_con.get('chart_data').decode()
            # ------------------- 组织数据 ---------------------
            con = json.loads(chart_data)
            con['start_day'] = '/'.join(start_day.split('-'))
            return JsonResponse(con)

    # √
    @classmethod
    def post(cls, request):
        """
        时间选择器
        :param request:
        :return:
        """
        # try:
            # if request.user.is_authenticated():
            # ---------------- 接收请求 --------------------------
        ret = eval(request.body.decode())
        # ---------------- 序列化查询数据 --------------------
        s = serBlackRecord()
        content = s.count_by_category(ret)
        #
        con = {
            'category': content
        }
        return JsonResponse(con)
        # except Exception:
            # traceback.print_exc()


# √
class HeatMapView(View):
    # √
    @classmethod
    def get(cls, request):
        """
        热力图
        :param request:
        :return:
        """
        ret = request.GET
        errlog.info(ret)
        heatmap_con = get_redis_connection('broadcast')
        heatmap_data = heatmap_con.get('heatmap_c').decode()
        con = json.loads(heatmap_data)
        return JsonResponse(con)

    # √
    @classmethod
    def post(cls, request):
        """
        时间选择器
        :param request:
        :return:
        """
        # if request.user.is_authenticated():
        # ------------ 检索请求 ----------------------------------
        ret = eval(request.body.decode())
        select_dict = dict()
        select_dict["s_time"] = t.heat_to_nomal(ret.get("s_time"))
        select_dict["e_time"] = t.heat_to_nomal(ret.get("e_time"))
        # -------------------------- 序列化获取数据 ----------------------
        s = serBlackRecord()
        info_list = s.select_info(select_dict)
        # ------------------------- 组织数据 ----------------------------
        content = list()
        for info in info_list:
            content.append(info.get("lnglat"))
        # ------------------------ 返回数据 -----------------------------
        con = {
            "code": code.STATUSCODE_SUCCESS,
            "msg": "success",
            "ret": content
        }
        return JsonResponse(con)
